#include "DXUT.h"
#include "VertexBuffer.h"
 



#pragma region VertexElementDeclare

 	 static const D3DVERTEXELEMENT9 elements0  []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,    D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     D3DDECLMETHOD_DEFAULT,   D3DDECLUSAGE_COLOR ,  0 },
		D3DDECL_END()
	} ;
 	static const D3DVERTEXELEMENT9 elements1  []  =

	{
		{0,0, D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION,  0 },
	    {1,0,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,   D3DDECLUSAGE_COLOR ,  0 },
		{2,0,D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,   D3DDECLUSAGE_TEXCOORD , 0 },
		D3DDECL_END()
	} ;

 	static const D3DVERTEXELEMENT9 elements2  []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		D3DDECL_END()
	} ;


 	static const D3DVERTEXELEMENT9 elements3  []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		{ 2,     0,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 0 },
		D3DDECL_END()
	} ;



 	static const D3DVERTEXELEMENT9 elements4  []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		{ 2,     0,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 0 },
		{ 2,     8,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 1 },
		D3DDECL_END()
	} ;



 	static const D3DVERTEXELEMENT9 elements5  []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		{ 2,     0,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 0 },
		{ 2,     8,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 1 },
		{ 2,     48,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 4 },
		D3DDECL_END()
	} ;





	static   const D3DVERTEXELEMENT9 elements6  []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		{ 2,     0,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 0 },
		{ 2,     8,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 1 },
		{ 2,     48,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 4 },

		{ 2,     56,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 5 },


		D3DDECL_END()
	} ;


	static   const D3DVERTEXELEMENT9 elements7 []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		{ 2,     0,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 0 },
		{ 2,     8,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 1 },
		{ 2,     48,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 4 },

		{ 2,     56,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 5 },

		{ 2,     64,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 6 },
		D3DDECL_END()
	} ;



 	static const D3DVERTEXELEMENT9 elements8 []  =

	{
		{ 0,     0, D3DDECLTYPE_FLOAT3,     0,  D3DDECLUSAGE_POSITION,  0 },
		{ 1,     0,D3DDECLTYPE_D3DCOLOR,     0,   D3DDECLUSAGE_COLOR ,  0 },
		{ 2,     16,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  2 },
		{ 2,     24,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD ,  3 },
		{ 2,     0,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 0 },
		{ 2,     8,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 1 },
		{ 2,     48,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 4 },

		{ 2,     56,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 5 },

		{ 2,     64,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 6 },
		{ 2,     72,D3DDECLTYPE_FLOAT2,     0,   D3DDECLUSAGE_TEXCOORD , 7 },
		D3DDECL_END()
	} ;



 
#pragma endregion VertexElementDeclare




void CVertexBuffer::OnD3D9DestroyDevice()
{
	 SAFE_RELEASE(m_pVertexDecl)
}

HRESULT CVertexBuffer::OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice )
{
	
	 CreateVertexBuffer();
	 CreateDiffuseVertexBuffer();
	 if(m_nTexture>0)
	 {
		 CreateTextureCoodVertexBuffer();
		 SetTextureCoodToUpdate();
	 }
	 SetVertextToUpdate();
	 SetDiffuseToUpdate();
	 UpdateToBuffer();

	 return S_OK;
}

void CVertexBuffer::OnD3D9LostDevice()
{
	
	 SAFE_RELEASE(m_pVertexBuffer);
	 SAFE_RELEASE(m_pDiffuseBuffer);
	 SAFE_RELEASE(m_pTextureCoodBuffer);
}

HRESULT CVertexBuffer::OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice )
{
	HRESULT hr;
	 V(pd3dDevice->CreateVertexDeclaration(  m_element,&m_pVertexDecl));

	 return hr;
}

 
CVertexBuffer::CVertexBuffer( const TCHAR * resName ,int numVertices ,const D3DVERTEXELEMENT9 * pVEM, int  nTexture,D3DPOOL pool/*=D3DPOOL_DEFAULT*/ )
:IResource(RESOURCE_TYPE_VERVERBUFFER,resName,pool)
,m_pVertexBuffer(0)
 ,m_pDiffuseBuffer(0)
 ,m_pTextureCoodBuffer(0)


 ,m_pVertexArray(0)
 ,m_pDiffuseArray(0)
 ,m_pTextureCoodArray(0)

  ,m_bUpdateVertexBuffer(false)
 ,m_bUpdateTextureCoodBffer(false)
 ,m_bUpdateDiffuseBuffer(false)

 ,m_pVertexDecl(0)
 ,m_element(pVEM)
 ,m_nVervices(numVertices)
  ,m_nTexture(nTexture)
{

 m_pVertexArray = new D3DXVECTOR3 [m_nVervices];
 m_pDiffuseArray=new D3DCOLOR [m_nVervices];
 if(m_nTexture>0)
 {
	 m_pTextureCoodArray=new D3DXVECTOR2  [m_nVervices];
 }
}

bool CVertexBuffer::UpdateToBuffer()
{
	assert(m_pVertexBuffer&& m_pDiffuseBuffer    ) ;
	 
	HRESULT hr;
	void * pVertexBuffer;
	if(m_bUpdateVertexBuffer)
	{
		    V( m_pVertexBuffer->Lock( 0, 0, (void**)&pVertexBuffer, D3DLOCK_DISCARD ) );
				memcpy(pVertexBuffer,m_pVertexArray,sizeof(D3DXVECTOR3)*m_nVervices);
			 V( m_pVertexBuffer->Unlock());
			 m_bUpdateVertexBuffer=false;
	}
		D3DCOLOR * pDiffuseBuffer;
	if(m_bUpdateDiffuseBuffer)
	{
		V( m_pDiffuseBuffer->Lock( 0, 0, (void**)&pDiffuseBuffer, D3DLOCK_DISCARD ) );
	 
		 memcpy(pDiffuseBuffer,m_pDiffuseArray,sizeof(D3DCOLOR)*m_nVervices);
		V( m_pDiffuseBuffer->Unlock());
		m_bUpdateDiffuseBuffer=false;
	}

	D3DXVECTOR2 * pTextureCood=0;

          
	  if( m_bUpdateTextureCoodBffer)
	 {
		 assert(m_pTextureCoodBuffer );
		 assert(m_pTextureCoodArray );
	 
		 
			 if(SUCCEEDED(hr=  m_pTextureCoodBuffer->Lock( 0, 0, (void**)&pTextureCood, D3DLOCK_DISCARD  )))
			 {	 
				 
				 memcpy(pTextureCood,m_pTextureCoodArray,sizeof(D3DXVECTOR2)*m_nVervices);

			     V( m_pTextureCoodBuffer->Unlock());
			 }
		      assert(SUCCEEDED(hr));
			 m_bUpdateTextureCoodBffer=false;
		 
	 }
	 return true;

	
}

void CVertexBuffer::CreateVertexBuffer()
{
	assert(m_pVertexArray);
	HRESULT hr;
	assert( m_pVertexBuffer==NULL );
	V(DXUTGetD3D9Device()->CreateVertexBuffer( m_nVervices * sizeof( D3DXVECTOR3 ), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,0, D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL ) );
}

void CVertexBuffer::CreateTextureCoodVertexBuffer()
{

 
	assert(m_nTexture>0&&m_pTextureCoodArray!=NULL);
	HRESULT hr;
	assert( m_pTextureCoodBuffer==NULL );
	V(DXUTGetD3D9Device()->CreateVertexBuffer( m_nVervices * sizeof( D3DXVECTOR2 ), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,0, D3DPOOL_DEFAULT, &m_pTextureCoodBuffer, NULL ) );
	assert( m_pTextureCoodBuffer!=NULL );

	

}

void CVertexBuffer::CreateDiffuseVertexBuffer()
{
	assert(m_pDiffuseArray);
	HRESULT hr;
	assert( m_pDiffuseBuffer==NULL );
	V(DXUTGetD3D9Device()->CreateVertexBuffer( m_nVervices * sizeof( D3DCOLOR ), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,0, D3DPOOL_DEFAULT, &m_pDiffuseBuffer, NULL ) );
}

CVertexBuffer::~CVertexBuffer()
{
	SAFE_DELETE_ARRAY(m_pTextureCoodArray);
	SAFE_DELETE_ARRAY(m_pDiffuseArray);
	SAFE_DELETE_ARRAY(m_pVertexArray);
}
